package middleware

import (
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"go-caipu/pkg/api/helper"
	"go-caipu/pkg/api/jwt"
	"go-caipu/pkg/constant"
	"go-caipu/pkg/infra/log"
	"go-caipu/pkg/services/monitor/onlineuser"
	"net/http"
)

func tokenCheck(ctx *gin.Context, j *jwt.JWT, logger log.Logger) (int64, error) {
	tokenString := ctx.Request.Header.Get(jwt.AUTH)
	if tokenString == "" {
		logger.Warn("请求未携带token，无权限访问: url:%s,params: %s", ctx.Request.URL, ctx.Params)
		return 0, errors.New(fmt.Sprintf("请求未携带token，无权限访问: url:%s,params: %s", ctx.Request.URL, ctx.Params))
	}

	claims, err := j.ParseToken(tokenString)
	if err != nil {
		logger.Error("jwt error: url:%s,params: %s", ctx.Request.URL, ctx.Params)
		return 0, errors.New(fmt.Sprintf("jwt error: url:%s,params: %s", ctx.Request.URL, ctx.Params))
	}
	return claims.UserId, nil
}

// AuthMiddleware 验证token有效性
func AuthMiddleware(j *jwt.JWT, onlineService onlineuser.Service, logger log.Logger) gin.HandlerFunc {
	return func(ctx *gin.Context) {
		_, err := tokenCheck(ctx, j, logger)
		if err != nil {
			helper.ErrorWithDetail(ctx, http.StatusUnauthorized, constant.ErrTokenParse, err)
			ctx.Abort()
			return
		}
		//验证通过，判断用户token是否有效
		if exists, _ := onlineService.IsSessionValid(ctx, j.GetTokenString(ctx.Request.Header.Get(jwt.AUTH))); !exists {
			//兼容前端http.ts文件：弹出提示框，提示用户登录会话失效
			ctx.JSON(200, map[string]interface{}{"code": "401", "msg": "登录会话失败，请重新登录！"})
			ctx.Abort()
			return
		}
		ctx.Next()
	}
}
